/*!
\copyright  Copyright (c) 2024-2025 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\ingroup    audio_domain
\defgroup   user_eq User EQ
\brief      User EQ API

This API allows direct control of the UserEQ.
Settings synchronization with other earbud is not covered by this component.

\note   In scope of this component 'kymera' term refers to kymera audio domain code in the application,
        not the kymera framework on DSP. And it is typically used to differentiate between 'kymera' and
        Audio Stack implementation of this component.

\note   In the current implementation only RTPEQ capability can be used with Audio Stack, 
        and only PEQ capability can be used with kymera implementation.

Usage
There are two scenarios in which User EQ component can be used:
1. GAIA scenario. User EQ is used together with the media player service, and the GAIA mobile application.
2. Customer scenario. The media player and GAIA is not used. The customer's code regiters callbacks using
UserEq_RegisterCallbacks() and it is responsible for settings syncronization with the peer earbud as well as
storing and restoring settings from NVM. 

Default behaviour
If neither UserEq_RegisterCallbacks() or UserEq_UseInternalCallbacks() is called then UserEQ will be put into BYPASS mode.

Expected sequence Customer scenario:
1. UserEq_Init()
2. Register callbacks providing initial settings for when use cases start by calling UserEq_RegisterCallbacks()
3. Check if UserEq_IsActive() is TRUE
4. Change preset by calling UserEq_SelectPreset()
5. Change gains by calling UserEq_SetUserEqGains()

Persistence
Last selected preset as well as all the gains for the customizable 'preset' are stored in NVM on every change.
Last selected preset and gains are restored on init.

*/

#ifndef USER_EQ_H_
#define USER_EQ_H_

#include <csrtypes.h>
#include <message.h>
#include <domain_message.h>
#include <user_eq_types.h>

#define EQ_BANK_USER 63

typedef enum
{
    /*! EQ available notification */
    USER_EQ_AVAILABLE = USER_EQ_MESSAGE_BASE,
    /*! EQ unavailable notification */
    USER_EQ_UNAVAILABLE,
    /*! EQ bands updated notification */
    USER_EQ_BANDS_UPDATED,

    /*! Dummy message for overflow checking */
    USER_EQ_MESSAGE_END
} user_eq_messages_t;

typedef struct
{
    /*! Number of the first band being changed */
    uint8 start_band;
    /*! Number of the last band being changed */
    uint8 end_band;
} USER_EQ_BANDS_UPDATED_T;

typedef struct user_eq_callbacks
{
    /*! \brief Callback to provide the inital preset
        
        This callback should return preset number that
        will be set when the graph is prepared.

        \return Preset to be used
    */
    uint8 (*GetInitialPreset)(void);

    /*! \brief Callback to provide the inital preset bypass state
        
        \return TRUE if bypass should be enabled, FALSE otherwise
    */
    bool (*GetInitialBypassState)(void);

    /*! \brief Callback to provide the initial set of gains

        This callback should return an array of gains that
        will be applied when the graph is prepared.

        /param gains Array of gains, in dB*60 format, to be populated.
        /param number_of_gains Number of gains are in the array.

        /return Array of gains in dB*60 format.
    */
    void (*GetInitialGains)(int16 *gains, uint8 number_of_gains);

    /*! \brief Callback indicating EQ activity change

        \param is_active TRUE if EQ is active and can accept commands,
                            FALSE otherwise.
    */
    void (*ActivityIndication)(bool is_active);
} user_eq_callbacks_t;

/*! \brief Initialize the UserEQ component
    
    \param init_task[in] Unused, this initialization is synchronous

    \return Always TRUE
*/
bool UserEq_Init(Task init_task);

/*! \brief Register set of the optional callbacks

    It should only be used in the Customer scenario.

    \param callbacks[in] See user_eq_callbacks_t for more information
*/
void UserEq_RegisterCallbacks(const user_eq_callbacks_t *callbacks);

/*! \brief Installs internal callback that implement GAIA scenario behaviour

    It must be called in GAIA scenario for the User EQ component to operate correctly.
*/
void UserEq_UseInternalCallbacks(void);

/*! \brief Register for user_eq_messages_t messages

    It is intended to be used in GAIA scenario, 
    but it has no impact on the User EQ component operation.

    \param task[in] Notifications will be sent to this task
*/
void UserEq_RegisterNotificationListener(Task task);

/*! \brief Indicates that User EQ is enabled in the product

    It is provided to preserve behaviour of kymera domain based implementation.

    \return TRUE if the UserEQ is present
*/
bool UserEq_IsPresent(void);

/*! \brief Indicates if the API alerting the state of the UserEQ can be used

    Note that currently it always returns TRUE.

    \return TRUE if the UserEQ is present in the currently running graph
*/
bool UserEq_IsActive(void);

/*! \brief Returns the maximum number of bands supported by the UserEQ

    For example UserEq_SetUserEqGains() file fail if end_band
    is greater or equal to the maximum number of bands supported by the UserEQ.

    \return The maximum number of bands supported by the UserEQ
*/
uint8 UserEq_GetNumberOfBands(void);

/*! \brief Returns the number of configured banks 

    \return The the number of configured banks, which includes all the presets and customizable preset.
*/
uint8 UserEq_GetNumberOfEqBanks(void);

/*! \brief Populates an array with ids on configured presets 

    It can be used to discover which presets are present in a product.
    Is is intended to be used in GAIA scenario.

    \note   Populated array won't contain preset 0 (FLAT) and 63 (user customizable),
            hence minimum preset array size is UserEq_GetNumberOfEqBanks() - 2

    \param presets[out] After calling this function presets will contain ids of configured presets.
                        Caller is responsible for allocating and freeing memory for presets.

    \return The the number of configured presets
*/
uint8 UserEq_PopulatePresets(uint8 *presets);

/*! \brief Select the UserEQ preset

    It can only be used when UserEq_IsActive() == TRUE

    \param preset[in] Number of a preset to select, valid range is from 0 to 63

    \return TRUE if action has been executed
*/
bool UserEq_SelectPreset(uint8 preset);

/*! \brief Get id of the selected preset

    \return Id of the selected preset
*/
uint8 UserEq_GetSelectedPreset(void);

/*!  \brief Apply currently selected preset and gains

    It is intended to be used by the kymera code during chain configuration.
*/
void UserEq_ApplyCurrentPresetAndGains(void);


/*! \brief Select the UserEQ gains

    It can only be used when UserEq_IsActive() == TRUE

    To modify one band use the same number for both start_band and end_band
    For example UserEq_SetUserEqGains(0, 0, gains) will set the gain for the first band
    and gains array must contain one element.
    UserEq_SetUserEqGains(1,2, gains) will set the gains for the second and third band
    and gains array must contain two elements.

    Maximum number of gains depends on audio capability that is used.
    For RTPEQ it is 8 which means range from 0 to 7 can by used.
    For PEQ it is 10 or 20 depending on platform.

    This API will keep track of all the gains and it will send all of them even if only one gain is set.
    All the gains are set to 0 by UserEq_Init()

    \param start_band[in] Begining of the range of bands to set gains for
    \param end_band[in] End of the range of bands to set gains for
    \param gains[in] Array of gains in dB*60

    \return TRUE if action has been executed
*/
bool UserEq_SetUserEqGains(uint8 start_band, uint8 end_band, int16 *gains);

/*! \brief Get gain for a band of customizable 'preset'

    \param band[in] Band number to get gain for, numbers are starting from 0

    \return Gain (in dB*60) for selected band
*/
int16 UserEq_GetUserEqGain(uint8 band);

/*! \brief Get full set of parameter for a band of customizable 'preset'

    It is intended for GAIA scenario.

    Parameters are:
        - filter type
        - cut off frequency
        - gain
        - Q parameter

    \param band[in] Band number to get parameters for, numbers are starting from 0
    \param param_set[out] Pointer to a structure containing parameters
*/
void UserEq_GetEqBandInformation(uint8 band, user_eq_parameter_set_t *param_set);

/*! \brief Turn the preset bypass on or off

    It can only be used when UserEq_IsActive() == TRUE

    Turning the bypass off restores the last used preset.

    \param enable_bypass[in] TRUE to enable bypass, FALSE to disable it

    \return TRUE if action has been executed
*/
bool UserEq_Bypass(bool enable_bypass);

#endif